public class code01 {
//    力扣 150 组合总和
//    解法一
public List<List<Integer>> combinationSum(int[] candidates, int target) {
    // 针对这道题目，首先需要做的是创建一个符合返回值条件的顺序表
    List<List<Integer>> re = new ArrayList<>();

    // 创建出一个存储当前一组的数据信息
    List<Integer> adds = new ArrayList<>();

    // 针对数组的特殊情况进行一下判断操作
    if(candidates.length == 0) {
        return re;
    }

    // 创建出一个回溯方法，用来针对每一层实现数据填充
    func(candidates, target, re, adds, 0);

    return re;
}

    // 实现回溯的核心方法
    // 简单说明一下这里传入的参数信息
    // 题目提供的数组、要求的目标值
    // 返回的链表、添加到当前一组的顺序表
    // 数组的下标信息(用于回溯查找合适的下标)
    private void func(int[] candidates, int target, List<List<Integer>> re, List<Integer> adds, int index) {
        // 首先确定一下返回条件
        if(index == candidates.length) {
            // 如果当前的下标值到达了数组的最大个数的位置
            // 此时说明没有符合的值，不做任何处理，直接返回即可
            return;
        }

        // 再来针对目标值进行判断
        if(target == 0) {
            // 因为是针对目标值和数组元素相减操作的，所以判断条件为目标值是不是为 0
            // 当出现为 0 的结果时，此时直接将值添加进来即可
            re.add(new ArrayList<>(adds));
            // 之后直接返回
            return;
        }

        // 之后进行递归回溯操作
        // 在进行递归操作时，是需要将数组的下标进行 +1 操作的
        // 这里的目的就是快速的递归到数组的最后一个元素的位置上，也就是最深处
        // 之后在通过回溯选择合适的值
        func(candidates, target, re, adds, index + 1);

        // 选择合适的值
        if(target - candidates[index] >= 0) {
            // 从后向前，此时就说明当前下标的值是符合题目要求的
            // 直接将当前的值进行存储操作
            adds.add(candidates[index]);

            // 再将新的 target 值针对当前下标的值进行递归操作
            // 目的是查看重复值相减的可行性
            func(candidates, target - candidates[index], re, adds, index);

            // 当一组递归结束后，需要清空一下 adds 顺序表中的参数信息
            adds.remove(adds.size() - 1);
        }
    }
}
